package com.example.studyPlatform.controller;

import com.example.studyPlatform.bean.Comment;
import com.example.studyPlatform.bean.User;
import com.example.studyPlatform.config.ThemeConfig;
import com.example.studyPlatform.controller.api.protocol.API_STATE;
import com.example.studyPlatform.exception.InvalidValidationException;
import com.example.studyPlatform.kit.EmailUtils;
import com.example.studyPlatform.service.protocol.LoginService;
import com.example.studyPlatform.service.protocol.RegisterService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.Optional;

import static com.example.studyPlatform.config.BaseConstant.MSG;
import static com.example.studyPlatform.config.BaseConstant.USR;
import static com.example.studyPlatform.config.RoutingConstant.*;
import static com.example.studyPlatform.controller.api.kit.JsonUtils.toJson;
import static com.example.studyPlatform.controller.api.kit.JsonUtils.toJsonAttachRemark;
import static com.example.studyPlatform.controller.api.protocol.API_STATE.CLIENT_ERR;
import static com.example.studyPlatform.controller.api.protocol.API_STATE.SUCCESS;

@Controller
@AllArgsConstructor
public class LoginController {
    LoginService loginService;
    RegisterService registerService;
    ThemeConfig themeConfig;
    EmailUtils emailUtils;

    final String LOGIN_ERROR = "密码或用户名错误";
    final String REGISTER_ERROR = "注册失败";
    final String REGISTER_BLANK_ERR = "用户名和密码不能为空";
    final String LOGIN_SUCCESS = "登录成功";
    final String REGISTER_SUCCESS = "注册成功";


    @PostMapping(LOGIN)
    String login(String username, String password, HttpSession session, Model model) {
        Optional<User> res = loginService.login(username, password);
        if (res.isEmpty()) {
            model.addAttribute(MSG, LOGIN_ERROR);
            return themeConfig.render(LOGIN);
        }
        session.setAttribute(USR, res.get());
        model.addAttribute(MSG, LOGIN_SUCCESS);
        return themeConfig.render(USER_INDEX);
    }

    @PostMapping(REGISTER)
    String register(String username, String password, String email, String verCode, HttpSession session, Model model) {
        String msg = REGISTER_ERROR;
        if (!StringUtils.isBlank(username) && !StringUtils.isBlank(password)) {
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            user.setEmail(email);
            try {
                if (registerService.register(user, verCode).isPresent()) {
                    model.addAttribute(MSG, REGISTER_SUCCESS);
                    session.setAttribute(USR, user);
                    return themeConfig.render(INDEX);
                }
            } catch (DuplicateKeyException e) {
                msg += " 用户名重复,请更换。";
            } catch (InvalidValidationException e2) {
                msg += " 验证码错误。";
            }
        } else {
            msg = REGISTER_BLANK_ERR;
        }
        model.addAttribute(MSG, msg);
        return themeConfig.render(REGISTER);
    }

    @GetMapping(API_PATH + "/login/checkName")
    @ResponseBody
    JsonNode checkName(String username) {
        if (StringUtils.isBlank(username))
            return toJson(CLIENT_ERR);
        if (registerService.checkUserName(username)) return toJson(SUCCESS);
        return toJsonAttachRemark(CLIENT_ERR, "该用户名已存在");
    }

    @ResponseBody
    @PostMapping(API_PATH + "/email")
    ObjectNode email(@RequestBody(required = true) Map<String, Object> map) throws Exception {
        emailUtils.sendEmail((String) map.get("email"));
        return toJson(API_STATE.SUCCESS);
    }
}
